package com.common.service.system.impl;

import com.common.converter.StandValueConverter;
import com.common.entity.standvalue.StandValueEntity;
import com.common.entity.system.DictionaryEntity;
import com.common.entity.system.QDictionaryEntity;
import com.common.query.QueryConditionVo;
import com.common.repository.system.DictionaryRepository;
import com.common.requestvo.system.DictionaryReqVo;
import com.common.requestvo.system.DictionaryTypeReq;
import com.common.service.system.DictionaryService;
import com.common.vo.standvalue.StandValueVo;
import com.querydsl.core.QueryResults;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


/**
 * @author johnny
 */
@Slf4j
@Service
@Transactional(rollbackOn = Exception.class)
public class DictionaryServiceImpl implements DictionaryService {

    private final DictionaryRepository dictionaryRepository;

    private final JPAQueryFactory queryFactory;

    public DictionaryServiceImpl(DictionaryRepository dictionaryRepository, JPAQueryFactory queryFactory) {
        this.dictionaryRepository = dictionaryRepository;
        this.queryFactory = queryFactory;
    }

    @Override
    public List<DictionaryEntity> findAll(Specification<DictionaryEntity> whereSpec) {
        return dictionaryRepository.findAll(whereSpec);
    }

    @Override
    public Page<DictionaryEntity> findAll(Specification<DictionaryEntity> whereSpec, Pageable pageable) {
        return dictionaryRepository.findAll(whereSpec, pageable);
    }

    @Override
    public List<DictionaryEntity> findByType(String[] typeArr) {

        List<DictionaryEntity> dictionaryEntityList = new ArrayList<>();
        Arrays.stream(typeArr).forEach(type -> {
            List<DictionaryEntity> byType = dictionaryRepository.findByType(type);
            dictionaryEntityList.addAll(byType);
        });
        return dictionaryEntityList;
    }

    @Override
    public void saveDic(DictionaryEntity dictionaryEntity) {
        dictionaryRepository.save(dictionaryEntity);
    }

    @Override
    public void editDic(DictionaryEntity dictionaryEntity) {
        DictionaryEntity oldDictionaryEntity = dictionaryRepository.findById(dictionaryEntity.getId()).orElse(null);
        if (oldDictionaryEntity != null) {
            BeanUtils.copyProperties(dictionaryEntity, oldDictionaryEntity);
            dictionaryRepository.save(oldDictionaryEntity);
        }
    }

    @Override
    public void delete(Long id) {
        dictionaryRepository.deleteById(id);
    }


    @Override
    public Page<DictionaryEntity> listByCondition(DictionaryReqVo dictionaryReqVo, Pageable pageable) {

        QDictionaryEntity qDictionaryEntity = QDictionaryEntity.dictionaryEntity;

        JPAQuery<DictionaryEntity> jpaQuery = queryFactory.select(qDictionaryEntity)
                .from(qDictionaryEntity)
                .offset(pageable.getPageNumber() * pageable.getPageSize())
                .limit(pageable.getPageSize());

        fillCondition(jpaQuery, dictionaryReqVo);
        QueryResults<DictionaryEntity> queryResults = jpaQuery.fetchResults();

        List<DictionaryEntity> list = new ArrayList<>(queryResults.getResults());
        return new PageImpl<>(list, pageable, queryResults.getTotal());
    }

    @Override
    public List<DictionaryEntity> findByTypeList(DictionaryTypeReq dictionaryTypeReq) {
        String[] typeArr = new String[dictionaryTypeReq.getTypeList().size()];
        for (int i = 0; i < dictionaryTypeReq.getTypeList().size(); i++) {
            typeArr[i] = dictionaryTypeReq.getTypeList().get(i);
        }
        return findByType(typeArr);
    }

    @Override
    public List<DictionaryEntity> findByTypeAndOrder(String type) {
        return dictionaryRepository.findByTypeOrderBySortNumAsc(type);
    }

    @Override
    public void fillCondition(JPAQuery<DictionaryEntity> jpaQuery, QueryConditionVo queryConditionVo) {
        QDictionaryEntity qDictionaryEntity = QDictionaryEntity.dictionaryEntity;
        DictionaryReqVo dictionaryReqVo = (DictionaryReqVo) queryConditionVo;
        if (StringUtils.isNotEmpty(dictionaryReqVo.getName())) {
            jpaQuery.where(qDictionaryEntity.name.like("%" + dictionaryReqVo.getName() + "%"));
        }
        if (StringUtils.isNotEmpty(dictionaryReqVo.getType())) {
            jpaQuery.where(qDictionaryEntity.type.eq(dictionaryReqVo.getType()));
        }
    }
}
